package com.xq.model.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.xq.config.properties.ManageProperties;
import com.xq.config.properties.MusicProperties;
import com.xq.model.dto.*;
import com.xq.model.element.SurfMinEle;
import com.xq.model.entity.TBaseDataRecord;
import com.xq.model.entity.TBaseSurfMin;
import com.xq.model.mapper.TBaseSurfMinMapper;
import com.xq.model.service.DataTransferService;
import com.xq.model.service.ITBaseDataRecordService;
import com.xq.model.service.ITBaseSurfMinService;
import com.xq.model.struct.UtilStruct;
import com.xq.model.utils.ParentUtils;
import com.xq.model.vo.DataRecordAddVo;
import com.xq.model.vo.DataRecordEditVo;
import com.xq.utils.MapUtil;
import com.xq.utils.SignGenUtil;
import com.xq.utils.ClassUtil;
import com.xq.utils.HttpUtils;
import com.xq.utils.JsonUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 服务实现类
 *
 * @author xu
 * 2021/8/20 10:49
 */
@Service
public class TBaseSurfMinServiceImpl extends ServiceImpl<TBaseSurfMinMapper, TBaseSurfMin> implements ITBaseSurfMinService {
    @Resource
    private ParentUtils parentUtils;
    @Resource
    private MusicProperties musicProperties;
    @Resource
    private UtilStruct utilStruct;
    @Resource
    private ManageProperties manageProperties;
    @Resource
    private TBaseSurfMinMapper surfMinMapper;
    @Resource
    private ITBaseDataRecordService dataRecordService;
    @Resource
    private DataTransferService dataTransferService;


    @Override
    public void againGetSurf(int nHour) throws IllegalAccessException, IOException, URISyntaxException {
        // 1 表示地面要素
        List<TBaseDataRecord> dataRecords = dataRecordService.missReportByTypeLeHour("1", nHour);
        if(dataRecords==null||dataRecords.size()==0){
            return;
        }
        // 循环访问数据
        for (TBaseDataRecord dataRecord : dataRecords) {
            if(StrUtil.isNotBlank(dataRecord.getMissReportStationIdCList())){
                requestSurfByTimesAndStaIdS(dataRecord.getTimes(),dataRecord.getMissReportStationIdCList(),dataRecord.getRequestNum());
            }
        }
    }

    /**
     * 循环根据站点ID以及时间访问
     * @param times 时间
     * @param ids 多个站点以逗号隔开
     */
    private void requestSurfByTimesAndStaIdS(String times,String ids,Long requestNum) throws IllegalAccessException, IOException, URISyntaxException {
        SurfEleByTimeAndStaIdDTO dto = new SurfEleByTimeAndStaIdDTO();
        // 初始化
        parentUtils.init(dto,musicProperties);
        dto.setInterfaceId("getSurfEleByTimeAndStaID");
        dto.setDataCode("SURF_WEA_CHN_MUL_MIN");
        dto.setElements(ClassUtil.objectToString(new SurfMinEle()));
        dto.setTimes(times);
        dto.setDataFormat("json");
        dto.setStaIds(ids);

        // 将对象转成map
        Map<String, String> signMap = MapUtil.beanToMap(dto);
        // 获取签名
        String sign = SignGenUtil.getSign(signMap);
        // 设置签名
        dto.setSign(sign);
        // 获取请求参数
        String params = MapUtil.toParamsFromMap(MapUtil.beanToMap(dto));

        // 请求到数据了 3代表超时的
        List<TBaseSurfMin> surfMinList = byParams(params,requestNum,"3");
        if(surfMinList == null || surfMinList.size() == 0){
            return;
        }
        DataRecordEditVo editVo = new DataRecordEditVo();
        editVo.setSurfMinList(surfMinList);
        editVo.setTimes(times);
        // 1表示地面要素
        editVo.setDataType("1");
        // 将对象的idc 提取出来形成新集合
        List<String> overTimeIdList =surfMinList.stream().map(TBaseSurfMin::getStation_id_c).collect(Collectors.toList());
        editVo.setOverTimeStationIdCList(overTimeIdList);
        // 就去存 不要犹豫
        dataRecordService.updateDataRecord(editVo);
    }

    @Override
    public void badSurf(List<TBaseSurfMin> surfMinList,String type) throws IOException {
        // 缺报的情况 由于数据库暂时没有这条数据 所以直接新增
        if("2".equals(type)){
            saveBatch(surfMinList);
            // 保存之后要将数据传输至云端
            postSurfMin(surfMinList);
        }

        // 超时报的情况 由于这条数据本身是缺报 故要查询出来
        if("3".equals(type)){
            for (TBaseSurfMin surfMin : surfMinList) {
                LambdaQueryWrapper<TBaseSurfMin> lqw = Wrappers.lambdaQuery();
                // 根据访问轮次以及区站号去查
                lqw
                        .eq(true,TBaseSurfMin::getRequestNum,surfMin.getRequestNum())
                        .eq(true,TBaseSurfMin::getStation_id_c,surfMin.getStation_id_c());
                Long surfId = getOne(lqw).getSurfId();
                surfMin.setSurfId(surfId);
                surfMin.setSurfType("3");
            }
            // 变成修改
            updateBatchById(surfMinList);
            // 发送超时数据给云端
            postOverSurfMin(surfMinList);
        }

    }

    @Override
    public void postOverSurfMin(List<TBaseSurfMin> surfMinList) throws IOException {
        String jsonStr =getJsonStrBySurfList(surfMinList);
        HttpUtils.sendPostJson(manageProperties.getHost()+manageProperties.getOverSurfMinPath(),jsonStr);
        // 记得把要素传输统计也一起送过去 1代表地面要素
        dataTransferService.postDataTransfer("1");
    }

    @Override
    public void postSurfMin(List<TBaseSurfMin> surfMinList) throws IOException {
        String jsonStr =getJsonStrBySurfList(surfMinList);
        HttpUtils.sendPostJson(manageProperties.getHost()+manageProperties.getSurfMinPath(),jsonStr);
        // 记得把要素传输统计也一起送过去 1代表地面要素
        dataTransferService.postDataTransfer("1");
    }

    private String getJsonStrBySurfList(List<TBaseSurfMin> surfMinList){
        List<PostSurfMinDTO> dtoList = new ArrayList<>();
        // 匹配 以及转换成传输得数据
        for (TBaseSurfMin surfMin : surfMinList) {
            PostSurfMinDTO dto = new PostSurfMinDTO();
            // 设置质控码
            dto.setQ1Pre(surfMin.getQ_pre());
            dto.setQ1Prs(surfMin.getQ_prs());
            dto.setQ1Rhu(surfMin.getQ_rhu());
            dto.setQ1Tem(surfMin.getQ_tem());
            dto.setQ1WinDInst(surfMin.getQ_win_d_inst());
            dto.setQ1WinSInst(surfMin.getQ_win_s_inst());
            // 设置要素
            dto.setPre(surfMin.getPre());
            dto.setPrs(surfMin.getPrs());
            dto.setRhu(surfMin.getRhu());
            dto.setTem(surfMin.getTem());
            dto.setWinDInst(surfMin.getWin_d_inst());
            dto.setWinSInst(surfMin.getWin_s_inst());

            dto.setLat(surfMin.getLat());
            dto.setLon(surfMin.getLon());
            dto.setStationIdC(surfMin.getStation_id_c());

            dto.setRequestNum(surfMin.getRequestNum());
            dto.setSurfType(surfMin.getSurfType());

            dtoList.add(dto);
        }
        return JSON.toJSONString(dtoList);
    }

    @Override
    public void searchSurfByRegion(String times, String adminCodes) throws IllegalAccessException, IOException, URISyntaxException {
        SurfMinByRegionDTO surfMinByRegionDTO =  new SurfMinByRegionDTO();
        // 初始化
        parentUtils.init(surfMinByRegionDTO,musicProperties);
        surfMinByRegionDTO.setInterfaceId("getSurfEleInRegionByTime");
        surfMinByRegionDTO.setDataCode("SURF_WEA_CHN_MUL_MIN");
        surfMinByRegionDTO.setElements(ClassUtil.objectToString(new SurfMinEle()));
        surfMinByRegionDTO.setTimes(times);
        // 暂时不限制
        //surfMinDTO.setLimitCnt("1");
        // 暂时不排序
        //surfMinByRegionDTO.setOrderBy("");
        surfMinByRegionDTO.setDataFormat("json");
        surfMinByRegionDTO.setAdminCodes(adminCodes);

        // 将对象转成map
        Map<String, String> signMap = MapUtil.beanToMap(surfMinByRegionDTO);
        // 获取签名
        String sign = SignGenUtil.getSign(signMap);

        surfMinByRegionDTO.setSign(sign);

        // 获取请求参数
        String params = MapUtil.toParamsFromMap(MapUtil.beanToMap(surfMinByRegionDTO));


        // 获取访问轮次
        long requestNum = surfMinMapper.selectMaxRequestNum() == null ? 0L : surfMinMapper.selectMaxRequestNum();
        // 自加1
        requestNum++;

        // 1-代表正常
        List<TBaseSurfMin> surfMinList = byParams(params,requestNum,"1");
        if(surfMinList==null || surfMinList.size() ==0){
            return;
        }
        // 保存数据
        saveBatch(surfMinList);

        // 保存到数据记录里面去
        saveDataRecord(times,surfMinList,requestNum);

        // 保存之后要将数据传输至云端
        postSurfMin(surfMinList);
    }

    @Override
    public void searchSurf(String times) throws IllegalAccessException, IOException, URISyntaxException {
//        SurfMinDTO surfMinDTO = new SurfMinDTO();
//        // 初始化
//        parentUtils.init(surfMinDTO,musicProperties);
//        surfMinDTO.setInterfaceId("getSurfEleByTime");
//        surfMinDTO.setDataCode("SURF_WEA_CHN_MUL_MIN");
//        surfMinDTO.setElements(ClassUtil.objectToString(new SurfMinEle()));
//        surfMinDTO.setTimes(times);
//        // 暂时不限制
//        //surfMinDTO.setLimitCnt("1");
//        surfMinDTO.setDataFormat("json");
//        surfMinDTO.setDistinct("true");
//
//        // 将对象转成map
//        Map<String, String> signMap = MapUtil.beanToMap(surfMinDTO);
//        // 获取签名
//        String sign = SignGenUtil.getSign(signMap);
//
//        surfMinDTO.setSign(sign);
//
//        // 获取请求参数
//        String params = MapUtil.toParamsFromMap(MapUtil.beanToMap(surfMinDTO));
//        // 请求到数据了
//        List<TBaseSurfMin> surfMinList = byParams(params);
//        if(surfMinList!=null && surfMinList.size()>0){
//            saveBatch(surfMinList);
//        }
    }


    /**
     * 根据参数获取请求数据
     * @param params 请求参数
     * @param requestNum 请求轮次
     * @param surfType 1-正常 2-未报 3-超时
     * @return
     * @throws IOException
     * @throws URISyntaxException
     */
    private List<TBaseSurfMin> byParams(String params,Long requestNum,String surfType) throws IOException, URISyntaxException {
        // 获取返回数据 jsonArray
        JSONArray restArray = HttpUtils.sendGetToList(musicProperties, params);
        // 不为空继续操作
        if(restArray == null){
            System.out.println("为什么又不上传数据");
            return null;
        }
        // 转成list对象
        List<SurfMinEle> eleList = JsonUtils.jsonToList(restArray.toJSONString(),SurfMinEle.class);
        // 没查到就算了
        if(eleList==null || eleList.size() ==0){
            return null;
        }
        List<TBaseSurfMin> surfMinList = utilStruct.eleListToEntityList(eleList);
        for (TBaseSurfMin surfMin : surfMinList) {
            // 设置访问轮次
            surfMin.setRequestNum(requestNum);
            // 设置要素类型为正常
            surfMin.setSurfType(surfType);
        }
        System.out.println("获取条数:"+surfMinList.size());
        return surfMinList;
    }

    private void saveDataRecord(String times,List<TBaseSurfMin> surfMinList,Long requestNum) throws IOException {
        DataRecordAddVo recordAddVo = new DataRecordAddVo();
        // 1 代表地面要素
        recordAddVo.setDataType("1");
        recordAddVo.setTimes(times);

        // 设置访问轮次
        recordAddVo.setRequestNum(requestNum);

        List<String> realReportStationIdCList = new ArrayList<>();
        surfMinList.forEach(x -> realReportStationIdCList.add(x.getStation_id_c()));
        // 设置已上报的idc 集合
        recordAddVo.setRealReportStationIdCList(realReportStationIdCList);
        // 保存一下咯
        dataRecordService.addDataRecord(recordAddVo);
    }
}
